package com.study.example.gameserver.admin.recharge;

import com.sparrow.cache.entity.EntityCache;
import com.sparrow.common.util.JsonUtil;
import com.sparrow.common.util.TimeUtil;
import com.sparrow.socket.http.bean.HttpResponse;
import com.study.example.gameserver.admin.recharge.domain.RechargeExtData;
import com.study.example.gameserver.admin.recharge.domain.RechargePayType;
import com.study.example.gameserver.admin.recharge.entity.RechargePay;
import com.study.example.gameserver.module.player.service.PlayerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.CompletableFuture;

@Component
public class RechargeService {

    private static final Logger logger = LoggerFactory.getLogger(RechargeService.class);

    @Autowired
    EntityCache<String, RechargePay> rechargePayCache;

    @Autowired
    PlayerService playerService;

    public boolean isOrderProcessed(String orderId) {
        RechargePay rechargePay = rechargePayCache.get(orderId);
        return rechargePay != null && rechargePay.getStatus() == 2;
    }

    public CompletableFuture<HttpResponse> recharge(String orderId, String accountId, Integer serverId, Long playerId, Integer money, RechargeExtData rechargeExtData, HttpResponse response) {
        CompletableFuture<HttpResponse> future = new CompletableFuture<>();

        RechargePay rechargePay = rechargePayCache.getOrCreate(orderId, (e) -> {
            e.setAccount(accountId);
            e.setServerId(serverId);
            e.setPlayerId(playerId);
            e.setMoney(money);
            e.setStatus(1);
            e.setCreateTime(TimeUtil.timestamp());
        });

        playerService.execPlayerAsync(playerId,  player -> {
            try {
                RechargePayType rechargePayType = RechargePayType.of(rechargeExtData.getType());
                if (rechargePayType == null) {
                    rechargeFail(future, response, "RechargePayType is null");
                    return;
                }
                if (rechargePay.getStatus() == 2) {
                    rechargeFail(future, response, "订单重复发货");
                    return;
                }

                rechargePayType.reward(player, money, rechargeExtData);

                response.addResult("code", 200);
                response.addResult("msg", "发货成功");
                future.complete(response);
                logger.info("发货成功: orderId={}, playerId={}, type={}, money={}, extData={}",
                        orderId, playerId, rechargeExtData.getType(), money, JsonUtil.toJSON(rechargeExtData));
                rechargePay.setStatus(2);
            } catch (Exception e) {
                rechargeFail(future, response, "发货异常");
                rechargePay.setStatus(3);
            } finally {
                rechargePay.update();//入库
            }
        });
        return future;
    }


    public CompletableFuture<HttpResponse> rechargeFail(CompletableFuture<HttpResponse> future, HttpResponse response, String msg) {
        rechargeFail0(response, msg);
        future.complete(response);
        return future;
    }

    public CompletableFuture<HttpResponse> rechargeFail(HttpResponse response, String msg) {
        CompletableFuture<HttpResponse> f = new CompletableFuture<>();
        return rechargeFail(f, response, msg);
    }

    private void rechargeFail0(HttpResponse response, String msg) {
        response.addResult("code", 400);
        response.addResult("msg", msg);
        logger.error("充值失败 msg:{}", msg);
    }
}
